//----------------------------------------------------------------------- 
// PDS WITSMLstudio Store, 2018.3
//
// Copyright 2018 PDS Americas LLC
// 
// Licensed under the PDS Open Source WITSML Product License Agreement (the
// "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//   
//     http://www.pds.group/WITSMLstudio/OpenSource/ProductLicenseAgreement
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-----------------------------------------------------------------------

// ----------------------------------------------------------------------
// <auto-generated>
//     Changes to this file may cause incorrect behavior and will be lost
//     if the code is regenerated.
// </auto-generated>
// ----------------------------------------------------------------------

using Energistics.DataAccess;
using Energistics.DataAccess.WITSML141;
using Energistics.DataAccess.WITSML141.ComponentSchemas;
using Energistics.DataAccess.WITSML141.ReferenceData;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;

namespace PDS.WITSMLstudio.Store.Data.FormationMarkers
{
    [TestClass]
    public partial class FormationMarker141StoreTests : FormationMarker141TestBase
    {
        public FormationMarker141StoreTests()
            : base(false)
        {
        }

        [TestMethod]
        public void FormationMarker141DataAdapter_GetFromStore_Can_Get_FormationMarker()
        {
            AddParents();
            DevKit.AddAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
            DevKit.GetAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
       }

        [TestMethod]
        public void FormationMarker141DataAdapter_AddToStore_Can_Add_FormationMarker()
        {
            AddParents();
            DevKit.AddAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
        }

        [TestMethod]
        public void FormationMarker141DataAdapter_UpdateInStore_Can_Update_FormationMarker()
        {
            AddParents();
            DevKit.AddAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
            DevKit.UpdateAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
            DevKit.GetAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
        }

        [TestMethod]
        public void FormationMarker141DataAdapter_DeleteFromStore_Can_Delete_FormationMarker()
        {
            AddParents();
            DevKit.AddAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
            DevKit.DeleteAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
            DevKit.GetAndAssert<FormationMarkerList, FormationMarker>(FormationMarker, isNotNull: false);
        }

        [TestMethod]
        public void FormationMarker141WitsmlStore_GetFromStore_Can_Transform_FormationMarker()
        {
            AddParents();
            DevKit.AddAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);

            // Re-initialize all capServer providers
            DevKit.Store.CapServerProviders = null;
            DevKit.Container.BuildUp(DevKit.Store);

            string typeIn, queryIn;
            var query = DevKit.List(DevKit.CreateQuery(FormationMarker));
            DevKit.SetupParameters<FormationMarkerList, FormationMarker>(query, ObjectTypes.FormationMarker, out typeIn, out queryIn);

            var options = OptionsIn.Join(OptionsIn.ReturnElements.All, OptionsIn.DataVersion.Version131);
            var request = new WMLS_GetFromStoreRequest(typeIn, queryIn, options, null);
            var response = DevKit.Store.WMLS_GetFromStore(request);

            Assert.IsFalse(string.IsNullOrWhiteSpace(response.XMLout));
            Assert.AreEqual((short)ErrorCodes.Success, response.Result);

            var result = WitsmlParser.Parse(response.XMLout);
            var version = ObjectTypes.GetVersion(result.Root);
            Assert.AreEqual(OptionsIn.DataVersion.Version131.Value, version);
        }

        [TestMethod]
        public void FormationMarker141DataAdapter_AddToStore_Creates_ChangeLog()
        {
            AddParents();

            DevKit.AddAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);

            var result = DevKit.GetAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
            var expectedHistoryCount = 1;
            var expectedChangeType = ChangeInfoType.add;
            DevKit.AssertChangeLog(result, expectedHistoryCount, expectedChangeType);
        }

        [TestMethod]
        public void FormationMarker141DataAdapter_UpdateInStore_Updates_ChangeLog()
        {
            AddParents();

            DevKit.AddAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);

            // Update the FormationMarker141
            FormationMarker.Name = "Change";
            DevKit.UpdateAndAssert(FormationMarker);

            var result = DevKit.GetAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
            var expectedHistoryCount = 2;
            var expectedChangeType = ChangeInfoType.update;
            DevKit.AssertChangeLog(result, expectedHistoryCount, expectedChangeType);
        }

        [TestMethod]
        public void FormationMarker141DataAdapter_DeleteFromStore_Updates_ChangeLog()
        {
            AddParents();

            DevKit.AddAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);

            // Delete the FormationMarker141
            DevKit.DeleteAndAssert(FormationMarker);

            var expectedHistoryCount = 2;
            var expectedChangeType = ChangeInfoType.delete;
            DevKit.AssertChangeLog(FormationMarker, expectedHistoryCount, expectedChangeType);
        }

        [TestMethod]
        public void FormationMarker141DataAdapter_ChangeLog_Tracks_ChangeHistory_For_Add_Update_Delete()
        {
            AddParents();

            // Add the FormationMarker141
            DevKit.AddAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);

            // Verify ChangeLog for Add
            var result = DevKit.GetAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
            var expectedHistoryCount = 1;
            var expectedChangeType = ChangeInfoType.add;
            DevKit.AssertChangeLog(result, expectedHistoryCount, expectedChangeType);

            // Update the FormationMarker141
            FormationMarker.Name = "Change";
            DevKit.UpdateAndAssert(FormationMarker);

            result = DevKit.GetAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
            expectedHistoryCount = 2;
            expectedChangeType = ChangeInfoType.update;
            DevKit.AssertChangeLog(result, expectedHistoryCount, expectedChangeType);

            // Delete the FormationMarker141
            DevKit.DeleteAndAssert(FormationMarker);

            expectedHistoryCount = 3;
            expectedChangeType = ChangeInfoType.delete;
            DevKit.AssertChangeLog(FormationMarker, expectedHistoryCount, expectedChangeType);

            // Re-add the same FormationMarker141...
            DevKit.AddAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);

            //... the same changeLog should be reused.
            result = DevKit.GetAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);
            expectedHistoryCount = 4;
            expectedChangeType = ChangeInfoType.add;
            DevKit.AssertChangeLog(result, expectedHistoryCount, expectedChangeType);

            DevKit.AssertChangeHistoryTimesUnique(result);
        }

        [TestMethod]
        public void FormationMarker141DataAdapter_GetFromStore_Filter_ExtensionNameValue()
        {
            AddParents();

            var extensionName1 = DevKit.ExtensionNameValue("Ext-1", "1.0", "m");
            var extensionName2 = DevKit.ExtensionNameValue("Ext-2", "2.0", "cm", PrimitiveType.@float);
            extensionName2.MeasureClass = MeasureClass.Length;
            var extensionName3 = DevKit.ExtensionNameValue("Ext-3", "3.0", "cm", PrimitiveType.unknown);

            FormationMarker.CommonData = new CommonData()
            {
                ExtensionNameValue = new List<ExtensionNameValue>()
                {
                    extensionName1, extensionName2, extensionName3
                }
            };

            // Add the FormationMarker141
            DevKit.AddAndAssert(FormationMarker);

            // Query for first extension
            var commonDataXml = "<commonData>" + Environment.NewLine +
                                "<extensionNameValue uid=\"\">" + Environment.NewLine +
                                "<name />{0}" + Environment.NewLine +
                                "</extensionNameValue>" + Environment.NewLine +
                                "</commonData>";

            var extValueQuery = string.Format(commonDataXml, "<dataType>double</dataType>");
            var queryXml = string.Format(BasicXMLTemplate, FormationMarker.UidWell, FormationMarker.UidWellbore, FormationMarker.Uid, extValueQuery);
            var result = DevKit.Query<FormationMarkerList, FormationMarker>(ObjectTypes.FormationMarker, queryXml, null, OptionsIn.ReturnElements.Requested);
            Assert.IsNotNull(result);
            Assert.AreEqual(1, result.Count);

            var resultFormationMarker = result[0];
            Assert.IsNotNull(resultFormationMarker);

            var commonData = resultFormationMarker.CommonData;
            Assert.IsNotNull(commonData);
            Assert.AreEqual(1, commonData.ExtensionNameValue.Count);

            var env = commonData.ExtensionNameValue[0];
            Assert.IsNotNull(env);
            Assert.AreEqual(extensionName1.Uid, env.Uid);
            Assert.AreEqual(extensionName1.Name, env.Name);

            // Query for second extension
            extValueQuery = string.Format(commonDataXml, "<measureClass>length</measureClass>");
            queryXml = string.Format(BasicXMLTemplate, FormationMarker.UidWell, FormationMarker.UidWellbore, FormationMarker.Uid, extValueQuery);
            result = DevKit.Query<FormationMarkerList, FormationMarker>(ObjectTypes.FormationMarker, queryXml, null, OptionsIn.ReturnElements.Requested);
            Assert.IsNotNull(result);
            Assert.AreEqual(1, result.Count);

            resultFormationMarker = result[0];
            Assert.IsNotNull(resultFormationMarker);

            commonData = resultFormationMarker.CommonData;
            Assert.IsNotNull(commonData);
            Assert.AreEqual(1, commonData.ExtensionNameValue.Count);

            env = commonData.ExtensionNameValue[0];
            Assert.IsNotNull(env);
            Assert.AreEqual(extensionName2.Uid, env.Uid);
            Assert.AreEqual(extensionName2.Name, env.Name);

            // Query for third extension
            extValueQuery = string.Format(commonDataXml, "<dataType>unknown</dataType>");
            queryXml = string.Format(BasicXMLTemplate, FormationMarker.UidWell, FormationMarker.UidWellbore, FormationMarker.Uid, extValueQuery);
            result = DevKit.Query<FormationMarkerList, FormationMarker>(ObjectTypes.FormationMarker, queryXml, null, OptionsIn.ReturnElements.Requested);
            Assert.IsNotNull(result);
            Assert.AreEqual(1, result.Count);

            resultFormationMarker = result[0];
            Assert.IsNotNull(resultFormationMarker);

            commonData = resultFormationMarker.CommonData;
            Assert.IsNotNull(commonData);
            Assert.AreEqual(1, commonData.ExtensionNameValue.Count);

            env = commonData.ExtensionNameValue[0];
            Assert.IsNotNull(env);
            Assert.AreEqual(extensionName3.Uid, env.Uid);
            Assert.AreEqual(extensionName3.Name, env.Name);
        }

        [TestMethod]
        public void FormationMarker141DataAdapter_ChangeLog_Syncs_FormationMarker_Name_Changes()
        {
            AddParents();

            // Add the FormationMarker141
            DevKit.AddAndAssert<FormationMarkerList, FormationMarker>(FormationMarker);

            // Assert that all FormationMarker names match corresponding changeLog names
            DevKit.AssertChangeLogNames(FormationMarker);

            // Update the FormationMarker141 names
            FormationMarker.Name = "Change";
            FormationMarker.NameWell = "Well Name Change";

            FormationMarker.NameWellbore = "Wellbore Name Change";

            DevKit.UpdateAndAssert(FormationMarker);

            // Assert that all FormationMarker names match corresponding changeLog names
            DevKit.AssertChangeLogNames(FormationMarker);
        }
    }
}